package me.szlx.validation.system;


import me.szlx.validation.Assert;
import me.szlx.validation.Constraint;

/**
 * 统一异常处理的基类，一个运行时异常。
 */
public class InvalidException extends RuntimeException {
    /**
     * 根据指定的规则创建异常。
     *
     * @param constraint 规则.
     */
    public InvalidException(Constraint constraint) {
        this(constraint, null, null);
    }

    /**
     * 根据指定的规则和规则描述创建异常。在异常中，{@code brief} 指定的规则描述将取代 {@code constraint}中的规则描述。
     *
     * @param constraint  规则。
     * @param brief 规则描述。
     */
    public InvalidException(Constraint constraint, String brief) {
        this(constraint, brief, null);
    }

    /**
     * 根据指定的规则和异常创建异常，参数{@code cause}指定的异常将成为新异常因由异常。
     *
     * @param constraint  规则。
     * @param cause 出错原因。
     */
    public InvalidException(Constraint constraint, Throwable cause) {
        this(constraint, null, cause);
    }

    /**
     * 根据指定的规则、规则描述和异常创建异常，参数{@code cause}指定的异常将成为新异常因由异常。
     *
     * @param constraint  规则。
     * @param brief 规则描述。
     * @param cause 出错原因。
     */
    public InvalidException(Constraint constraint, String brief, Throwable cause) {
        super(buildMessage(constraint, brief));
    }

    /**
     * 根据出错规格返回出错字符串。
     *
     * @param constraint 出错规格
     * @return 出错信息字符串
     */
    private static String buildMessage(Constraint constraint, String brief) {
        Assert.constraintNotNull(constraint);
        return String.format("%s - %s", constraint.code(), brief != null ? brief : constraint.brief());
    }

    public static class InvalidationHandler extends AbstractInvalidationHandler {
        @Override
        protected void doHandle(Constraint constraint, Throwable cause) {
            Assert.constraintNotNull(constraint);
            throw  new InvalidException(constraint, cause);
        }
    }
}
